using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Reflection;
using PandoraCommon;

namespace PandoraGPS
{
    public partial class frmMain : Form
    {
        private List<ILogReader> logReaders = new List<ILogReader>();
        private List<ILogWriter> logWriters = new List<ILogWriter>();
        private List<GpsPosition> activeGpsPositions = null;

        /// <summary>
        /// Initializes a new instance of the <see cref="frmMain"/> class.
        /// </summary>
        public frmMain()
        {
            InitializeComponent();
        }

        /// <summary>
        /// Handles the Load event of the frmMain control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void frmMain_Load(object sender, EventArgs e)
        {
            Cursor.Current = Cursors.WaitCursor;
            Version currentVersion = Assembly.GetExecutingAssembly().GetName().Version;

            this.Text = "Pandora GPS Beta (" + 
                        currentVersion.Major.ToString() + "." + currentVersion.Minor.ToString() + "." + currentVersion.Revision.ToString() + 
                        ")";

            listGpsReaders.Items.Clear();
            listGpsWriters.Items.Clear();

            try
            {
                DirectoryInfo pluginsFolder = new DirectoryInfo(Application.StartupPath + "\\plugins");
                foreach (FileInfo currentFile in pluginsFolder.GetFiles("*.dll"))
                {
                    Assembly currentPlugIn = Assembly.LoadFile(currentFile.FullName);
                    Type[] definedTypes = currentPlugIn.GetTypes();
                    for (int i = 0; i < definedTypes.Length; i++)
                    {
                        Type[] interfaces = definedTypes[i].GetInterfaces();
                        for (int j = 0; j < interfaces.Length; j++)
                        {
                            if (interfaces[j] == typeof(ILogReader))
                            {
                                ILogReader newReader = (ILogReader)Activator.CreateInstance(definedTypes[i]);
                                listGpsReaders.Items.Add(newReader.Name);
                                logReaders.Add(newReader);
                            }
                            else if (interfaces[j] == typeof(ILogWriter))
                            {
                                ILogWriter newWriter = (ILogWriter)Activator.CreateInstance(definedTypes[i]);
                                listGpsWriters.Items.Add(newWriter.Name);
                                logWriters.Add(newWriter);
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Error loading plugins: " + ex.Message);
            }
            finally
            {
                Cursor.Current = Cursors.Default;
            }
        }

        /// <summary>
        /// Handles the Click event of the btReadGpsData control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void btReadGpsData_Click(object sender, EventArgs e)
        {
            if (listGpsReaders.SelectedIndex != -1)
            {
                Cursor.Current = Cursors.WaitCursor;

                try
                {
                    ILogReader activeReader = getActiveLogReader();
                    activeGpsPositions = activeReader.ReadLog();
                    gridPositionsRead.DataSource = activeGpsPositions;
                    gridPositionsRead.Refresh();
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Error loading plugins: " + ex.Message + " >> " + ex.StackTrace);
                }
                finally
                {
                    Cursor.Current = Cursors.Default;
                }
            }
        }

        /// <summary>
        /// Handles the Click event of the btWriteGpsData control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void btWriteGpsData_Click(object sender, EventArgs e)
        {
            if (activeGpsPositions != null && activeGpsPositions.Count > 0)
            {
                if (listGpsWriters.SelectedIndex != -1)
                {
                    Cursor.Current = Cursors.WaitCursor;

                    try
                    {
                        ILogWriter activeReader = getActiveLogWriter();
                        activeReader.WriteLog(this.activeGpsPositions);
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show("Error loading plugins: " + ex.Message + " >> " + ex.StackTrace);
                    }
                    finally
                    {
                        Cursor.Current = Cursors.Default;
                    }
                }
            }
            else
            {
                MessageBox.Show("You must first load positions to memory using the \"Read\" funcionality.", "Pandora");
            }
        }

        /// <summary>
        /// Gets the active log reader.
        /// </summary>
        /// <returns></returns>
        private ILogReader getActiveLogReader()
        {
            return logReaders.Find(findActiveLogReader);
        }

        /// <summary>
        /// Predicate function to find the active log reader.
        /// </summary>
        /// <param name="reader">The reader.</param>
        /// <returns></returns>
        private bool findActiveLogReader(ILogReader reader)
        {
            return reader.Name == listGpsReaders.Items[listGpsReaders.SelectedIndex].ToString();
        }

        /// <summary>
        /// Gets the active log writer.
        /// </summary>
        /// <returns></returns>
        private ILogWriter getActiveLogWriter()
        {
            return logWriters.Find(findActiveLogWriter);
        }

        /// <summary>
        /// Predicate function to find the active log writer.
        /// </summary>
        /// <param name="reader">The writer.</param>
        /// <returns></returns>
        private bool findActiveLogWriter(ILogWriter writer)
        {
            return writer.Name == listGpsWriters.Items[listGpsWriters.SelectedIndex].ToString();
        }

        private void listGpsReaders_SelectedIndexChanged(object sender, EventArgs e)
        {
            txtDescription.Text = logReaders[listGpsReaders.SelectedIndex].Description;
        }
    }
}